package com.xuanyue.db.xuan.sdk.client.pool;

import java.io.Closeable;
import java.io.IOException;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

import com.xuanyue.db.xuan.netty.coder.X2YMsgDecoder;
import com.xuanyue.db.xuan.netty.coder.X2YMsgEecoder;
import com.xuanyue.db.xuan.sdk.client.ClientHandler;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class ChannelFactory extends BasePooledObjectFactory<Channel> implements Closeable{

	
	private EventLoopGroup group;
	private String host;
	private int port;
	
	public ChannelFactory( String host, int port,EventLoopGroup group) {
		super();
		this.group = group;
		this.host = host;
		this.port = port;
	}

	
	
	@Override
	public PooledObject<Channel> makeObject() throws Exception {
		return new DefaultPooledObject<>(create());
	}

	@Override
	public Channel create() throws Exception {
		Bootstrap bs = new Bootstrap();
		bs.group(group);
		bs.channel(NioSocketChannel.class);
		bs.option(ChannelOption.AUTO_READ, true);
		bs.remoteAddress(host, port);
		bs.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(
                		new X2YMsgDecoder(),
                		new X2YMsgEecoder(),
                        ClientHandler.getInstance());
            }
        });
		ChannelFuture f = bs.connect().sync();
		return f.channel();
	}




	@Override
	public PooledObject<Channel> wrap(Channel obj) {
		return new DefaultPooledObject<>(obj);
	}

	@Override
	public void destroyObject(PooledObject<Channel> p) throws Exception {
		Channel c = p.getObject();
		c.close();
	}

	@Override
	public boolean validateObject(PooledObject<Channel> p) {
		Channel c = p.getObject();
		return c.isActive();
	}



	@Override
	public void close() throws IOException {
		group.shutdownGracefully();
	}





	


	
	
	
}
